/*
 * @Author: Troubadour 2276791354@qq.com
 * @Date: 2024-08-16 22:29:25
 * @LastEditors: Troubadour 2276791354@qq.com
 * @LastEditTime: 2024-08-18 12:00:23
 * @Version:
 * @Description:
 */

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Include file                                                                       -
--------------------------------------------------------------------------------------------------------------------------------------*/
#include "tft_gui.h"
#include "tft_drv.h"
#include "Font.h"
/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal macro                                                                     -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal enum                                                                      -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal structure                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal function                                                                  -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Internal variables                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  External variables                                                                 -
--------------------------------------------------------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------------------------------------------------------
-                                                  Function body                                                                      -
--------------------------------------------------------------------------------------------------------------------------------------*/

// void TFT_DrawPoint(uint8_t x, uint8_t y, uint16_t Data)
// {

// }
void TFT_SetXY(uint8_t x, uint8_t y)
{

}

uint16_t TFT_GUI_BGR2RGB(uint16_t coloc)
{
    uint16_t coloc_r, coloc_g, coloc_b, coloc_rgb;
    coloc_b = (coloc >> 0) & 0x1F;
    coloc_g = (coloc >> 5) & 0x3F;
    coloc_r = (coloc >> 11) & 0x1F;
    coloc_rgb = (coloc_b << 11) + (coloc_g << 5) + (coloc_r << 0);
    return (coloc_rgb);
}

void TFT_GUI_Circle(uint16_t X, uint16_t Y, uint16_t R, uint16_t fc)
{
    uint16_t a, b;
    int c;
    a = 0;
    b = R;
    c = 3 - 2 * R;
    while (a < b)
    {
        TFT_DrawPoint(X + a, Y + b, fc); //        7
        TFT_DrawPoint(X - a, Y + b, fc); //        6
        TFT_DrawPoint(X + a, Y - b, fc); //        2
        TFT_DrawPoint(X - a, Y - b, fc); //        3
        TFT_DrawPoint(X + b, Y + a, fc); //        8
        TFT_DrawPoint(X - b, Y + a, fc); //        5
        TFT_DrawPoint(X + b, Y - a, fc); //        1
        TFT_DrawPoint(X - b, Y - a, fc); //        4

        if (c < 0)
            c = c + 4 * a + 6;
        else
        {
            c = c + 4 * (a - b) + 10;
            b -= 1;
        }
        a += 1;
    }
    if (a == b)
    {
        TFT_DrawPoint(X + a, Y + b, fc);
        TFT_DrawPoint(X + a, Y + b, fc);
        TFT_DrawPoint(X + a, Y - b, fc);
        TFT_DrawPoint(X - a, Y - b, fc);
        TFT_DrawPoint(X + b, Y + a, fc);
        TFT_DrawPoint(X - b, Y + a, fc);
        TFT_DrawPoint(X + b, Y - a, fc);
        TFT_DrawPoint(X - b, Y - a, fc);
    }
}

void TFT_GUI_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Color)
{
    int dx,  // difference in x's
        dy,  // difference in y's
        dx2, // dx,dy * 2
        dy2,
        x_inc, // amount in pixel space to move during drawing
        y_inc, // amount in pixel space to move during drawing
        error, // the discriminant i.e. error i.e. decision variable
        index; // used for looping

    TFT_SetXY(x0, y0);
    dx = x1 - x0; // 计算x距离
    dy = y1 - y0; // 计算y距离

    if (dx >= 0)
    {
        x_inc = 1;
    }
    else
    {
        x_inc = -1;
        dx = -dx;
    }

    if (dy >= 0)
    {
        y_inc = 1;
    }
    else
    {
        y_inc = -1;
        dy = -dy;
    }

    dx2 = dx << 1;
    dy2 = dy << 1;

    if (dx > dy) // x距离大于y距离，那么每个x轴上只有一个点，每个y轴上有若干个点
    {            // 且线的点数等于x距离，以x轴递增画点
        // initialize error term
        error = dy2 - dx;

        // draw the line
        for (index = 0; index <= dx; index++) // 要画的点数不会超过x距离
        {
            // 画点
            TFT_DrawPoint(x0, y0, Color);

            // test if error has overflowed
            if (error >= 0) // 是否需要增加y坐标值
            {
                error -= dx2;

                // move to next line
                y0 += y_inc; // 增加y坐标值
            } // end if error overflowed

            // adjust the error term
            error += dy2;

            // move to the next pixel
            x0 += x_inc; // x坐标值每次画点后都递增1
        } // end for
    } // end if |slope| <= 1
    else // y轴大于x轴，则每个y轴上只有一个点，x轴若干个点
    {    // 以y轴为递增画点
        // initialize error term
        error = dx2 - dy;

        // draw the line
        for (index = 0; index <= dy; index++)
        {
            // set the pixel
            TFT_DrawPoint(x0, y0, Color);

            // test if error overflowed
            if (error >= 0)
            {
                error -= dy2;

                // move to next line
                x0 += x_inc;
            } // end if error overflowed

            // adjust the error term
            error += dx2;

            // move to the next pixel
            y0 += y_inc;
        } // end for
    } // end else |slope| > 1
}

void Gui_DrawFont_GBK16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s)
{
    unsigned char i, j;
    unsigned short k, x0;
    x0 = x;

    while (*s)
    {
        if ((*s) < 128)
        {
            k = *s;
            if (k == 13)
            {
                x = x0;
                y += 16;
            }
            else
            {
                if (k > 32)
                    k -= 32;
                else
                    k = 0;

                for (i = 0; i < 16; i++)
                    for (j = 0; j < 8; j++)
                    {
                        if (asc16[k * 16 + i] & (0x80 >> j))
                            TFT_DrawPoint(x + j, y + i, fc);
                        else
                        {
                            if (fc != bc)
                                TFT_DrawPoint(x + j, y + i, bc);
                        }
                    }
                x += 8;
            }
            s++;
        }

        else
        {
            for (k = 0; k < hz16_num; k++)
            {
                if ((hz16[k].Index[0] == *(s)) && (hz16[k].Index[1] == *(s + 1)))
                {
                    for (i = 0; i < 16; i++)
                    {
                        for (j = 0; j < 8; j++)
                        {
                            if (hz16[k].Msk[i * 2] & (0x80 >> j))
                                TFT_DrawPoint(x + j, y + i, fc);
                            else if (fc != bc)
                            {
                                TFT_DrawPoint(x + j, y + i, bc);
                            }
                        }
                        for (j = 0; j < 8; j++)
                        {
                            if (hz16[k].Msk[i * 2 + 1] & (0x80 >> j))
                                TFT_DrawPoint(x + j + 8, y + i, fc);
                            else if (fc != bc)
                            {
                                TFT_DrawPoint(x + j + 8, y + i, bc);
                            }
                        }
                    }
                }
            }
            s += 2;
            x += 16;
        }
    }
}

void Gui_DrawFont_Num32(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint16_t num)
{
    uint8_t i, j, k, c;

    for (i = 0; i < 32; i++)
    {
        for (j = 0; j < 4; j++)
        {
            c = *(sz32 + num * 32 * 4 + i * 4 + j);
            for (k = 0; k < 8; k++)
            {

                if (c & (0x80 >> k))
                    TFT_DrawPoint(x + j * 8 + k, y + i, fc);
                else if (fc != bc)
                {
                    TFT_DrawPoint(x + j * 8 + k, y + i, bc);
                }
            }
        }
    }
}
